Option Explicit On
Option Strict On

Imports NStl.SyntaxHelper.Compose
Imports NUnit.Framework
Imports NStl.Iterators.Support

Imports nstl
Imports NStl.SyntaxHelper

Namespace nstl.test
    <TestFixture()> _
    Public Class AlgorithmTest

        ''' <summary>
        ''' Initialize() is called once during test execution before
        ''' test methods in this test class are executed.
        ''' </summary>
        <SetUp()> Public Sub Initialize()
            ' TODO: Add test initialization code
        End Sub

        ''' <summary>
        ''' Cleanup() is called once during test execution after
        ''' test methods in this class have executed unless the
        ''' corresponding Initialize() call threw an exception.
        ''' </summary>
        <TearDown()> Public Sub Cleanup()
            ' TODO: Add test cleanup code
        End Sub

        <Test()> _
        Public Sub find_if()
            'find_if_input_it()
            find_if_fwd_it()
            find_if_rand_it()
        End Sub
        Public Sub find_if_rand_it()
            Dim v1 As New Vector(Of Integer)(-2, -1, 0, 1, 2, 3, 4)

            'Test forward iterator version
            Dim pos As Vector(Of Integer).Iterator = _
               Algorithm.FindIf(v1.Begin(), v1.End(), Bind.Second(Compare.Greater(Of Integer)(), 1))
            Assert.IsTrue(NStlUtil.Distance(v1.Begin, pos) = 4)


            pos = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.GreaterEqual(Of Integer)(), 3))
            Assert.IsTrue(NStlUtil.Distance(v1.Begin, pos) = 5)

            pos = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.GreaterEqual(Of Integer)(), 42))
            Assert.AreEqual(v1.End(), pos)
        End Sub
        Private Sub find_if_fwd_it()
            Dim v1 As New Vector(Of Integer)(-2, -1, 0, 1, 2, 3, 4)

            'Test forward iterator version
            Dim pos As ForwardIteratorProxy(Of Integer) = _
               Algorithm.FindIf(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.Greater(Of Integer)(), 1))
            Assert.IsTrue(NStlUtil.Distance(New ForwardIteratorProxy(Of Integer)(v1.Begin), pos) = 4)


            pos = Algorithm.FindIf(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.GreaterEqual(Of Integer)(), 3))
            Assert.IsTrue(NStlUtil.Distance(New ForwardIteratorProxy(Of Integer)(v1.Begin), pos) = 5)

            pos = Algorithm.FindIf(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.GreaterEqual(Of Integer)(), 42))
            Assert.AreEqual(New ForwardIteratorProxy(Of Integer)(v1.End()), pos)
        End Sub



        <Test()> _
        Public Sub find()
            Dim v1 As New Vector(Of Integer)(-2, -1, 0, 1, 2, 3, 4)

            'Test forward iterator version
            Dim pos As Vector(Of Integer).Iterator = Algorithm.Find(v1.Begin, v1.End, 1)
            Assert.AreNotEqual(pos, v1.End())
            Dim i As Integer = NStlUtil.Distance(v1.Begin, pos)
            Assert.IsTrue(NStlUtil.Distance(v1.Begin, pos) = 3)
            Assert.AreEqual(pos.Value, 1)

            pos = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.GreaterEqual(Of Integer)(), 42))
            Assert.AreEqual(v1.End(), pos)
        End Sub
        <Test()> _
        Public Sub remove_copy_if()
            Dim v1 As New Vector(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            Dim v2 As New Vector(Of Integer)
            Algorithm.RemoveCopyIf(v1.Begin, v1.End, NStlUtil.BackInserter(v2), Bind.Second(Compare.GreaterEqual(Of Integer), 7))
            Assert.IsTrue(TestUtil.equal(v2, New Vector(Of Integer)(1, 2, 0, 3, 4, 6, 5)))
        End Sub
        <Test()> _
        Public Sub remove_copy()
            Dim v1 As New Vector(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            Dim v2 As New Vector(Of Integer)
            Algorithm.RemoveCopy(v1.Begin, v1.End, NStlUtil.BackInserter(v2), 7)
            Assert.IsTrue(TestUtil.equal(v2, New Vector(Of Integer)(1, 9, 2, 0, 3, 4, 6, 8, 5)))
        End Sub
        <Test()> _
        Public Sub remove_if()
            Dim v1 As New Vector(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            v1.Erase(Algorithm.RemoveIf(v1.Begin, v1.End, Bind.Second(Compare.Greater(Of Integer)(), 3)), v1.End())
            Assert.IsTrue(TestUtil.equal(v1, New Vector(Of Integer)(1, 2, 0, 3)))
        End Sub
        <Test()> _
        Public Sub remove()
            Dim v1 As New Vector(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            v1.Erase(Algorithm.Remove(v1.Begin, v1.End, 7), v1.End())
            Assert.IsTrue(TestUtil.equal(v1, New Vector(Of Integer)(1, 9, 2, 0, 3, 4, 6, 8, 5)))
        End Sub
        <Test()> _
        Public Sub copy()
            Dim v1 As New DList(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            Dim v2 As New Vector(Of Integer)
            v2.Resize(v1.Count)
            Dim i As Vector(Of Integer).Iterator = Algorithm.Copy(v1.Begin, v1.End, v2.Begin())
            Assert.IsTrue(TestUtil.equal(v1, v2))
        End Sub
        <Test()> _
        Public Sub copy_if()
            Dim v1 As New DList(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            Dim v2 As New Vector(Of Integer)
            Algorithm.CopyIf(v1.Begin, v1.End, NStlUtil.BackInserter(v2), Bind.Second(Compare.Greater(Of Integer)(), 4))
            Assert.IsTrue(TestUtil.equal(v2, New Vector(Of Integer)(7, 9, 7, 7, 6, 8, 5, 7, 7)))
        End Sub
        <Test()> _
        Public Sub set_difference()
            Dim v1 As New DList(Of Integer)(-1, 0, 1, 2, 3, 4)
            Dim v2 As New Vector(Of Integer)(-3, -2, -1, 0)
            Dim v3 As New Vector(Of Integer)

            Algorithm.SetDifference(v1.Begin, v1.End, v2.Begin, v2.End, NStlUtil.BackInserter(v3), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Integer)(1, 2, 3, 4)))

            ' using a different sorter
            v1 = New DList(Of Integer)(0, -1, 1, 2, 3, 4)
            v2 = New Vector(Of Integer)(0, -1, -2, -3)
            v3 = New Vector(Of Integer)

            Algorithm.SetDifference(v1.Begin, v1.End, v2.Begin, v2.End, NStlUtil.BackInserter(v3), New mod_less_int())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Integer)(1, 4)))
        End Sub
        <Test()> _
        Public Sub set_intersection()
            Dim l1 As New DList(Of Integer)(-1, 0, 1, 2, 3)
            Dim v2 As New Vector(Of Integer)(-3, -2, -1, 0, 1)
            Dim v3 As New Vector(Of Integer)

            Algorithm.SetIntersection(l1.Begin, l1.End, v2.Begin, v2.End, NStlUtil.BackInserter(v3), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Integer)(-1, 0, 1)))

            ' using a different sorter
            l1 = New DList(Of Integer)(0, -1, 1, 2, 3)
            v2 = New Vector(Of Integer)(0, -1, 1, -2, -3)
            v3 = New Vector(Of Integer)

            Algorithm.SetIntersection(l1.Begin, l1.End, v2.Begin, v2.End, NStlUtil.BackInserter(v3), New mod_less_int())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Integer)(0, -1, 1, 2, 3)))
        End Sub
        <Test()> _
            Public Sub set_symmetric_difference()
            Dim v1 As New DList(Of Integer)(-1, 0, 1, 2, 3, 4)
            Dim v2 As New Vector(Of Integer)(-3, -2, -1, 0)
            Dim v3 As New Vector(Of Integer)

            Algorithm.SetSymmetricDifference(v1.Begin, v1.End, v2.Begin, v2.End, NStlUtil.BackInserter(v3), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Integer)(-3, -2, 1, 2, 3, 4)))

            ' using a different sorter
            v1 = New DList(Of Integer)(0, -1, 1, 2, 3, 4)
            v2 = New Vector(Of Integer)(0, -1, -2, -3)
            v3 = New Vector(Of Integer)

            Algorithm.SetSymmetricDifference(v1.Begin, v1.End, v2.Begin, v2.End, NStlUtil.BackInserter(v3), New mod_less_int())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Integer)(1, 4)))
        End Sub
        <Test()> _
        Public Sub set_union()
            Dim v1a As New DList(Of Integer)(New Integer() {-1, 0, 1, 2, 3})
            Dim v1b As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1})
            Dim v1c As New Vector(Of Integer)
            Algorithm.SetUnion(v1a.Begin, v1a.End, v1b.Begin, v1b.End, NStlUtil.BackInserter(v1c), Compare.Less(Of Integer)())

            Assert.IsTrue(TestUtil.equal(v1c, New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3})))
        End Sub
        <Test()> _
        Public Sub transform1()
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New DList(Of Single)
            Algorithm.Transform(v1.Begin, v1.End, NStlUtil.BackInserter(v2), New int2single())
            Assert.IsTrue(TestUtil.equal(v2, New Vector(Of Single)(New Single() {0.0F, 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F, 8.0F, 9.0F})))
        End Sub
        <Test()> _
        Public Sub transform2()
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New DList(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14})
            Dim v3 As New Vector(Of Single)
            Algorithm.Transform(v1.Begin, v1.End, v2.Begin, NStlUtil.BackInserter(v3), New int2single())
            Assert.IsTrue(TestUtil.equal(v3, New Vector(Of Single)(New Single() {0.0F, 2.0F, 4.0F, 6.0F, 8.0F, 10.0F, 12.0F, 14.0F, 16.0F, 18.0F})))
        End Sub
        <Test()> _
        Public Sub adjacent_find()
            Dim ints As Integer() = {1, 2, 3, 4, 4, 5, 6, 7}
            'Find the first pair of matching consecutive elements
            'in the range [first, last]
            'This version performs matching using equal_to
            Dim location As ListIterator(Of Integer) = Algorithm.AdjacentFind(NStlUtil.Begin(ints), NStlUtil.End(ints), Compare.EqualTo(Of Integer)())
            Assert.IsTrue(Not location.Equals(NStlUtil.End(ints)))
            Assert.AreEqual(location.Value, 4)
        End Sub
        <Test()> _
        Public Sub lower_bound()
            Dim numbers As Integer() = {4, 10, 70, 10, 30, 69, 96, 100}

            'sort the array, usng on board capabilities
            Array.Sort(numbers) '4,10,10,30,69,70,96,100

            Dim location As ListIterator(Of Integer) = Algorithm.LowerBound(NStlUtil.Begin(numbers), NStlUtil.End(numbers), 10, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, NStlUtil.End(numbers))
            Assert.AreEqual(location.Value, 10)
            Assert.IsTrue(NStlUtil.Distance(NStlUtil.Begin(numbers), location) = 1)

            location = Algorithm.LowerBound(NStlUtil.Begin(numbers), NStlUtil.End(numbers), 1, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, NStlUtil.End(numbers))
            Assert.AreEqual(location.Value, 4)

            location = Algorithm.LowerBound(NStlUtil.Begin(numbers), NStlUtil.End(numbers), 5, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, NStlUtil.End(numbers))
            Assert.AreEqual(location.Value, 10)

            location = Algorithm.LowerBound(NStlUtil.Begin(numbers), NStlUtil.End(numbers), 200, Compare.Less(Of Integer)())
            Assert.AreEqual(location, NStlUtil.End(numbers))

            location = Algorithm.LowerBound(NStlUtil.Begin(numbers), NStlUtil.End(numbers), 4, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, NStlUtil.End(numbers))
            Assert.AreEqual(location.Value, 4)
        End Sub
        <Test()> _
        Public Sub binary_search()
            Dim numbers As Integer() = {50, 10, 30, 20, 25, 5}

            'sort the array, usng on board capabilities
            Array.Sort(numbers)
            Dim fwd As ListIterator(Of Integer) = Algorithm.BinarySearch(NStlUtil.Begin(numbers), NStlUtil.End(numbers), 10, Compare.Less(Of Integer)())
            Assert.AreNotEqual(fwd, (NStlUtil.End(numbers)), "10 is NOT part of the range")
            Assert.IsTrue(NStlUtil.Distance(NStlUtil.Begin(numbers), fwd) = 1, "FAILED")

            Dim numbers2 As Integer() = {3, 4, -1, 1, -2, 0, 2}
            Array.Sort(numbers2, New mod_less_int)

            Assert.AreNotEqual(Algorithm.BinarySearch(NStlUtil.Begin(numbers2), NStlUtil.End(numbers2), -3, New mod_less_int), NStlUtil.End(numbers2), "FAILED")
        End Sub
        <Test()> _
        Public Sub copy_backwards()
            Dim v1 As New Vector(Of Integer)
            Dim v2 As New DList(Of Integer)
            For i As Integer = 0 To 5
                v1.PushBack(i * 10)
            Next
            For i As Integer = 0 To 10
                v2.PushBack(i * 3)
            Next

            Algorithm.CopyBackward(v1.Begin(), NStlUtil.Advance(Of Integer, Vector(Of Integer).Iterator)(v1.Begin(), 3), NStlUtil.Advance(Of Integer, DList(Of Integer).Iterator)(v2.Begin(), 7))

            Algorithm.CopyBackward(NStlUtil.Advance(Of Integer, DList(Of Integer).Iterator)(v2.Begin(), 4), NStlUtil.Advance(Of Integer, DList(Of Integer).Iterator)(v2.Begin(), 7), NStlUtil.Advance(Of Integer, DList(Of Integer).Iterator)(v2.Begin(), 9))


            'expected
            'v1 = ( 0 10 20 30 40 50 )
            'v2 = ( 0 3 6 9 12 15 18 21 24 27 30 )
            'v2 with v1 insert = ( 0 3 6 9 0 10 20 21 24 27 30 )
            'v2 with shifted insert = ( 0 3 6 9 0 10 0 10 20 27 30 )

            Assert.IsTrue(TestUtil.equal(v2, New Integer() {0, 3, 6, 9, 0, 10, 0, 10, 20, 27, 30}))
        End Sub
        <Test()> _
        Public Sub count_if()
            Dim names As New Vector(Of String)
            names.PushBack("She")
            names.PushBack("Sells")
            names.PushBack("Sea")
            names.PushBack("Shells")
            names.PushBack("by")
            names.PushBack("the")
            names.PushBack("Sea")
            names.PushBack("Shore")

            'Count the Element with the letter S
            Dim countS As Integer = Algorithm.CountIf(names.Begin(), names.End(), Bind.Second(New MatchFirstChar, "S"c))
            Assert.AreEqual(countS, 6)
        End Sub
        <Test()> _
        Public Sub mismatch()
            Dim v1 As New Vector(Of Integer)(1, 2, 6, 5, 9, 8, 10, 33)
            Dim v2 As New DList(Of Integer)(1, 2, 3, 4, 5, 6, 75, 88)
            Dim v3 As New Vector(Of Integer)(1, 2, 6, 5, 9, 8, 10, 33)

            Dim b As Vector(Of Integer).Iterator = v1.Begin
            Dim res As System.Collections.Generic.KeyValuePair(Of Vector(Of Integer).Iterator, DList(Of Integer).Iterator) = _
                Algorithm.Mismatch(v1.Begin(), v1.End(), v2.Begin(), Compare.EqualTo(Of Integer)())
            Assert.IsFalse(res.Key.Equals(v1.End()))
            Assert.IsFalse(res.Value.Equals(v2.End()))

            Dim res2 As System.Collections.Generic.KeyValuePair(Of Vector(Of Integer).Iterator, Vector(Of Integer).Iterator) = _
                 Algorithm.Mismatch(v1.Begin(), v1.End(), v3.Begin(), Compare.EqualTo(Of Integer)())
            Assert.IsTrue(res2.Key.Equals(v1.End()))
            Assert.IsTrue(res2.Value.Equals(v3.End()))

        End Sub
        <Test()> _
        Public Sub equal()
            Dim words As New Vector(Of String)
            words.PushBack("She")
            words.PushBack("Sells")
            words.PushBack("Sea")
            words.PushBack("Shells")
            words.PushBack("by")
            words.PushBack("the")
            words.PushBack("Sea")
            words.PushBack("Shore")

            'copy the vector
            Dim copiedWords As New DList(Of String)
            Algorithm.Copy(words.Begin(), words.End(), NStlUtil.BackInserter(copiedWords))

            Assert.IsTrue(Algorithm.Equal(words.Begin(), words.End(), copiedWords.Begin(), Compare.EqualTo(Of String)()))
        End Sub
        <Test()> _
        Public Sub equal_range()
            Dim v As New Vector(Of Integer)(-1, 0, 1, 2, 3, 4)

            Dim erange As Range(Of Integer, Vector(Of Integer).Iterator) _
                            = Algorithm.EqualRange(v.Begin, v.End, 3, Compare.Less(Of Integer)())
            Assert.AreEqual(erange.Begin.Value, 3)
            Assert.AreEqual(erange.End.Value, 4)

            Dim v1 As New Vector(Of Integer)(-3, -2, -1, -1, 0, 0, 1, 2, 3, 4) 'less
            Dim v2 As New Vector(Of Integer)(4, 3, 2, 1, 0, 0, -1, -1, -2, -3) 'greater
            Dim v3 As New Vector(Of Integer)(0, 0, -1, -1, 1, -2, 2, -3, 3, 4) 'mod_less

            erange = Algorithm.EqualRange(v1.Begin, v1.End, 3, Compare.Less(Of Integer)())
            Assert.AreEqual(erange.Begin.Value, 3)
            Assert.AreEqual(erange.End.Value, 4)
            Assert.IsTrue(TestUtil.equal(Of Integer)(erange.Begin, erange.End, New Integer() {3}))

            erange = Algorithm.EqualRange(v2.Begin, v2.End, 3, Compare.Greater(Of Integer)())
            Assert.AreEqual(erange.Begin.Value, 3)
            Assert.AreEqual(erange.End.Value, 2)
            Assert.IsTrue(TestUtil.equal(Of Integer)(erange.Begin, erange.End, New Integer() {3}))

            erange = Algorithm.EqualRange(v3.Begin, v3.End, 3, New mod_less_int())
            Assert.AreEqual(erange.Begin.Value, -3)
            Assert.AreEqual(erange.End.Value, 4)
            Assert.IsTrue(TestUtil.equal(Of Integer)(erange.Begin, erange.End, New Integer() {-3, 3}))
        End Sub
        <Test()> _
        Public Sub upper_bound()
            Dim numbers As New Vector(Of Integer)(4, 10, 10, 30, 69, 70, 96, 100)

            Dim location As Vector(Of Integer).Iterator = Algorithm.UpperBound(numbers.Begin, numbers.End, 10, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, numbers.End())
            Assert.AreEqual(location.Value, 30)
        End Sub
        <Test()> _
        Public Sub fill_n()
            Dim v As New Vector(Of Integer)()
            Algorithm.FillN(NStlUtil.BackInserter(v), 10, 42)
            Assert.IsTrue(TestUtil.equal(v, New Integer() {42, 42, 42, 42, 42, 42, 42, 42, 42, 42}))
        End Sub
        <Test()> _
        Public Sub pushHeap()
            Dim v1 As New Vector(Of Integer)(9, 2, 7, 3, 1, 6, 8, 4, 5)

            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Less(Of Integer)())

            v1.PushBack(10)

            Algorithm.PushHeap(v1.Begin, v1.End, Compare.Less(Of Integer)())

            Assert.IsTrue(TestUtil.equal(v1, New Integer() {10, 9, 8, 4, 5, 6, 7, 2, 3, 1}))

            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())

            v1.PushBack(0)
            Algorithm.PushHeap(v1.Begin, v1.End, Compare.Greater(Of Integer)())

            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 6, 3, 2, 8, 7, 4, 10, 9, 5}))
        End Sub
        <Test()> _
        Public Sub makeHeap()
            Dim v1 As New Vector(Of Integer)(8, 1, 9, 2, 0, 5, 7, 3, 4, 6)

            Algorithm.MakeHeap(v1.Begin(), v1.End())


            Assert.IsTrue(TestUtil.equal(v1, New Integer() {9, 6, 8, 4, 1, 5, 7, 3, 2, 0}))

            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 5, 2, 6, 8, 7, 3, 4, 9}))
        End Sub
        <Test()> _
       Public Sub popHeap()
            Dim v1 As New Vector(Of Integer)(9, 2, 7, 3, 1, 6, 8, 4, 5)

            Algorithm.MakeHeap(v1.Begin, v1.End)

            v1.PushBack(10)
            Algorithm.PushHeap(v1.Begin(), v1.End())

            'Remove the largest element from the heap
            Algorithm.PopHeap(v1.Begin(), v1.End())
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {9, 5, 8, 4, 1, 6, 7, 2, 3, 10}))


            'Make v1 a heap with greater-than ordering with a 0 element
            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())
            v1.PushBack(0)
            'Application of popHeap to remove the smallest element
            Algorithm.PushHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())

            Algorithm.PopHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())

            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {1, 2, 6, 3, 5, 8, 7, 4, 9, 10, 0}))
        End Sub
        <Test()> _
        Public Sub sortHeap()
            Dim v1 As New Vector(Of Integer)(9, 2, 7, 3, 1, 6, 8, 4, 5)

            'Algorithm.makeHeap(v1.begin, v1.end)
            Algorithm.SortHeap(v1.Begin, v1.End, Compare.Less(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 8, 7, 9})))
        End Sub
        <Test()> _
        Public Sub partial_sort()
            Dim v As New Vector(Of Integer)(0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11)

            Algorithm.PartialSort(v.Begin, v.Begin() + 6, v.End)
            Assert.IsFalse(TestUtil.mismatch(v, New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 10, 8, 6, 7, 9, 11})))

            Algorithm.PartialSort(v.Begin, v.Begin() + 4, v.End, Compare.Greater(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v, New Vector(Of Integer)(New Integer() {11, 10, 9, 8, 0, 1, 2, 3, 4, 5, 6, 7})))

            Algorithm.PartialSort(v.Begin, v.Begin() + 8, v.End, New UDgreater)
            Assert.IsFalse(TestUtil.mismatch(v, New Vector(Of Integer)(New Integer() {11, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3})))
        End Sub

        <Test()> _
        Public Sub search()

            Dim v1 As New Vector(Of Integer)(0, 5, 10, 15, 20, 25, 0, 5, 10, 15, 20, 25)
            Dim l1 As New DList(Of Integer)(New Integer() {20, 25})
            Dim v2 As New DList(Of Integer)(New Integer() {20, 30, 40})

            Dim pos As Vector(Of Integer).Iterator = _
                Algorithm.Search(Of Integer, Vector(Of Integer).Iterator)(v1.Begin, v1.End, l1.Begin, l1.End)
            Assert.IsTrue(Not pos.Equals(v1.End))
            Assert.IsTrue(CType(pos.Value, Integer) = 20)

            pos = Algorithm.Search(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.IsTrue(Not pos.Equals(v1.End))
            Assert.IsTrue(CType(pos.Value, Integer) = 10)

            pos = Algorithm.Search(pos + 1, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.IsTrue(Not pos.Equals(v1.End))
            Assert.IsTrue(CType(pos.Value, Integer) = 10)

        End Sub
        <Test()> _
        Public Sub search_n()
            Dim v1 As New Vector(Of Integer)(0, 5, 10, 15, 20, 25, 5, 5, 5, 0, 5, 10, 10, 10, 25, 5, 5, 5)
            '                                                      ^First hit      ^second hit using equal_twice        

            Dim r1 As Vector(Of Integer).Iterator = Algorithm.SearchN(v1.Begin, v1.End, 3, 5, Compare.EqualTo(Of Integer)())
            Assert.AreNotEqual(r1, v1.End())
            Assert.IsTrue(NStlUtil.Distance(v1.Begin(), r1) = 6)

            r1 = Algorithm.SearchN(v1.Begin, v1.End, 3, 20, New equal_twice)
            Assert.AreNotEqual(r1, v1.End())
            Assert.IsTrue(NStlUtil.Distance(v1.Begin(), r1) = 11)

        End Sub


        <Test()> _
        Public Sub find_end()

            Dim v1 As New Vector(Of Integer)(0, 5, 10, 15, 20, 25, 0, 5, 10, 15, 20, 25)
            '                                0  1   2   3   4   5  6  7   8   9  10  11   12
            Dim l1 As New DList(Of Integer)(New Integer() {5, 10, 15, 20})
            Dim v2 As New Vector(Of Integer)(20, 30, 40)
            Dim v3 As New Vector(Of Integer)(100, 200, 300)

            Dim result As Vector(Of Integer).Iterator = Algorithm.FindEnd(v1.Begin, v1.End, l1.Begin, l1.End, Compare.EqualTo(Of Integer)())
            Assert.AreEqual(result.Value, l1.Front())
            Assert.AreEqual(NStlUtil.Distance(v1.Begin, result), 7)

            result = Algorithm.FindEnd(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.AreEqual(result.Value, CType(v2.Front() / 2, Integer))
            Assert.AreEqual(NStlUtil.Distance(v1.Begin, result), 8)

            result = Algorithm.FindEnd(v1.Begin, v1.End, v3.Begin, v3.End, Compare.EqualTo(Of Integer)())
            Assert.AreEqual(result, v1.End())
        End Sub
        <Test()> _
        Public Sub find_first_of()
            Dim v1 As New Vector(Of Integer)(0, 5, 10, 15, 20, 25, 0, 5, 10, 15, 20, 25)
            '                                0  1   2   3   4   5   6 7   8   9  10  11   12
            Dim l1 As New DList(Of Integer)(New Integer() {15, 20})
            Dim v2 As New Vector(Of Integer)(20, 30, 40)

            Dim result As Vector(Of Integer).Iterator = Algorithm.FindFirstOf(v1.Begin, v1.End, l1.Begin, l1.End)
            Assert.IsTrue(NStlUtil.Distance(v1.Begin, result) = 3)

            result = Algorithm.FindFirstOf(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.IsTrue(NStlUtil.Distance(v1.Begin, result) = 2)

        End Sub
        <Test()> _
        Public Sub generate_it()
            Dim v1 As New Vector(Of Integer)(10)

            Algorithm.Generate(v1.Begin, v1.End, New IntGenerator())
            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}))
        End Sub
        <Test()> _
        Public Sub generate_n()
            Dim v1 As New Vector(Of Integer)(10)

            Algorithm.GenerateN(v1.Begin, 10, New IntGenerator())
            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}))
        End Sub
        <Test()> _
        Public Sub includes()
            'vectors sorted with less
            Dim v1a As New Vector(Of Integer)(-2, -1, 0, 1, 2, 3, 4)
            Dim v1b As New DList(Of Integer)(New Integer() {-2, -1, 0, 1, 2, 3})

            'vectors sorted with greater:
            Dim v2a As New Vector(Of Integer)(4, 3, 2, 1, 0, -1)
            Dim v2b As New DList(Of Integer)(New Integer() {2, 1, 0, -1, -2})

            'vectors sorted with abs_mod_less
            Dim v3a As New Vector(Of Integer)(0, 1, 2, 3, 4)
            Dim v3b As New DList(Of Integer)(0, -1, 1, -2, 2, 3)

            Assert.IsTrue(Algorithm.Includes(v1a.Begin, v1a.End, v1b.Begin, v1b.End, Compare.Less(Of Integer)()))
            Assert.IsFalse(Algorithm.Includes(v2a.Begin, v2a.End, v2b.Begin, v2b.End, Compare.Greater(Of Integer)()))
            Assert.IsFalse(Algorithm.Includes(v3a.Begin, v3a.End, v3b.Begin, v3b.End, New mod_less_int))
        End Sub
        <Test()> _
        Public Sub sort()
            Dim v1 As New Vector(Of Integer)(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50)
            Dim v2 As New Vector(Of Integer)
            Dim v3 As New Vector(Of Integer)
            Algorithm.Copy(v1.RBegin, v1.REnd, NStlUtil.BackInserter(v2))
            Algorithm.Copy(v1.Begin, v1.End, NStlUtil.BackInserter(v3))
            Algorithm.RandomShuffle(v1.Begin(), v1.End())
            Algorithm.Sort(v1.Begin(), v1.End(), Compare.Less(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, v3))

            Algorithm.Sort(v1.Begin, v1.End, Compare.Greater(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, v2))

            'retest with a small vector, as this will trigger a different control path
            Dim v4 As New Vector(Of Integer)(0, 1, 1, 2, 3, 4, 5, 6, 7, 8)
            Dim v5 As New Vector(Of Integer)
            Algorithm.Copy(v4.Begin, v4.End, NStlUtil.BackInserter(v5))

            Algorithm.RandomShuffle(v4.Begin, v4.End())

            Algorithm.Sort(v4.Begin, v4.End, Compare.Less(Of Integer)())

            Assert.IsFalse(TestUtil.mismatch(v4, v5))

        End Sub
        <Test()> _
        Public Sub merge()
            'vectors sorted with less
            Dim v1a As New Vector(Of Integer)(0, 1, 2, 3, 4, 5)
            Dim v1b As New DList(Of Integer)(-5, -4, -3, -2, -1, 0)

            'vectors sorted with greater:
            Dim v2a As New Vector(Of Integer)(5, 4, 3, 2, 1, 0)
            Dim v2b As New DList(Of Integer)(0, -1, -2, -3, -4, -5)

            'vectors sorted with abs_mod_less
            Dim v3a As New Vector(Of Integer)(0, 1, 2, 3, 4, 5)
            Dim v3b As New DList(Of Integer)(0, -1, -2, -3, -4, -5)

            Dim v1mod As New Vector(Of Integer)
            Dim v1mod_exp As New Vector(Of Integer)(-5, -4, -3, -2, -1, 0, 0, 1, 2, 3, 4, 5)
            Algorithm.Merge(v1a.Begin, v1a.End, v1b.Begin, v1b.End, NStlUtil.BackInserter(v1mod), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v1mod, v1mod_exp))

            Dim v2mod As New Vector(Of Integer)
            Dim v2mod_exp As New Vector(Of Integer)(5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5)
            Algorithm.Merge(v2a.Begin, v2a.End, v2b.Begin, v2b.End, NStlUtil.BackInserter(v2mod), Compare.Greater(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v2mod, v2mod_exp))

            Dim v3mod As New Vector(Of Integer)
            Algorithm.Merge(v3a.Begin, v3a.End, v3b.Begin, v3b.End, NStlUtil.BackInserter(v3mod), New mod_less_int)
            Assert.IsTrue(TestUtil.equal(v3mod, 0, 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5))

        End Sub
        <Test()> _
        Public Sub swap_ranges()
            Dim v1 As New Vector(Of Integer)(New Integer() {6, 6, 6, 6, 6, 6, 6, 6})
            Dim v11 As New Vector(Of Integer)(v1)
            Dim v2 As New DList(Of Integer)(New Integer() {0, 2, 5, 4, 8, 9, 7, 2})
            Dim v22 As New Vector(Of Integer)(v2.Begin(), v2.End())

            Algorithm.SwapRanges(v1.Begin, v1.End, v2.Begin)
            Assert.IsFalse(TestUtil.mismatch(v1, v22))
            Assert.IsFalse(TestUtil.mismatch(v2, v11))
        End Sub
        <Test()> _
        Public Sub reverse()
            reverse_rnd_it()
            reverse_bidit()
        End Sub
        Private Shared Sub reverse_rnd_it()
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New Vector(Of Integer)(New Integer() {9, 8, 7, 6, 5, 4, 3, 2, 1, 0})

            Algorithm.Reverse(v1.Begin, v1.End)
            Assert.IsTrue(TestUtil.equal(v1, v2))
        End Sub
        Private Shared Sub reverse_bidit()
            Dim v1 As New DList(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New DList(Of Integer)(New Integer() {9, 8, 7, 6, 5, 4, 3, 2, 1, 0})

            Algorithm.Reverse(v1.Begin, v1.End)
            Assert.IsTrue(TestUtil.equal(v1, v2))
        End Sub
        <Test()> _
        Public Sub reverse_copy()
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New Vector(Of Integer)
            Algorithm.ReverseCopy(v1.Begin, v1.End, NStlUtil.BackInserter(v2))
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(New Integer() {9, 8, 7, 6, 5, 4, 3, 2, 1, 0})))
        End Sub
        <Test()> _
        Public Sub rotate_copy()
            Dim v1 As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v2 As New Vector(Of Integer)
            Algorithm.RotateCopy(v1.Begin, NStlUtil.Advance(Of Integer, Vector(Of Integer).Iterator)(v1.Begin, 3), v1.End, NStlUtil.BackInserter(v2))
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})))
        End Sub
        Private Shared Sub rotate_fwd_it()
            Dim v1 As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v2 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})

            Algorithm.Rotate(Of Integer, ForwardIteratorProxy(Of Integer))(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.Begin + 3), New ForwardIteratorProxy(Of Integer)(v1.End))

            Assert.IsFalse(TestUtil.mismatch(v1, v2))
        End Sub
        Private Shared Sub rotate_bidit_it()
            Dim v1 As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v2 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})

            Algorithm.Rotate(Of Integer, BidirectionalIteratorProxy(Of Integer))(New BidirectionalIteratorProxy(Of Integer)(v1.Begin), New BidirectionalIteratorProxy(Of Integer)(v1.Begin + 3), New BidirectionalIteratorProxy(Of Integer)(v1.End))

            Assert.IsFalse(TestUtil.mismatch(v1, v2))
        End Sub
        Private Shared Sub rotate_rnd_it()
            Dim v11 As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v12 As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v21 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})
            Dim v22 As New Vector(Of Integer)(New Integer() {2, 3, 4, 5, -3, -2, -1, 0, 1})

            Algorithm.Rotate(Of Integer, Vector(Of Integer).Iterator)(v11.Begin, v11.Begin + 3, v11.End)
            Assert.IsFalse(TestUtil.mismatch(v11, v21))

            Algorithm.Rotate(Of Integer, Vector(Of Integer).Iterator)(v12.Begin, v12.Begin + 5, v12.End)
            Assert.IsFalse(TestUtil.mismatch(v12, v22))
        End Sub

        <Test()> _
        Public Sub rotate()
            rotate_fwd_it()
            rotate_bidit_it()
            rotate_rnd_it()
        End Sub
        <Test()> _
        Public Sub inplace_merge()
            Dim v11 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, 0})
            Dim v12 As New DList(Of Integer)(New Integer() {-5, -4, -3, -2, -1, 0, 0, 1, 2, 3, 4, 5})
            Algorithm.InplaceMerge(v11.Begin, Algorithm.Find(v11.Begin, v11.End, -5), v11.End, Compare.Less(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v11, v12))

            Dim v21 As New Vector(Of Integer)(New Integer() {5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5})
            Dim v22 As New DList(Of Integer)(New Integer() {5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5})
            Algorithm.InplaceMerge(v21.Begin, NStlUtil.Advance(Of Integer, Vector(Of Integer).Iterator)(Algorithm.Find(v21.Begin, v21.End, 0), -1), v21.End, Compare.Greater(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v21, v22))

            Dim v31 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 0, -1, -2, -3, -4, -5})
            Dim v32 As New DList(Of Integer)(New Integer() {0, 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5})
            Algorithm.InplaceMerge(v31.Begin, NStlUtil.Advance(Of Integer, Vector(Of Integer).Iterator)(v31.Begin(), 6), v31.End, New mod_less_int)
            Assert.IsFalse(TestUtil.mismatch(v31, v32))
        End Sub
        <Test()> _
        Public Sub lexicographical_compare()
            Dim v1 As New Vector(Of Integer)(0, 5, 10, 15, 20, 25)
            Dim l2 As New Vector(Of Integer)(0, 5, 10, 15, 20, 25, 30)
            Dim v2 As New Vector(Of Integer)(0, 10, 20, 30, 40, 50)

            Assert.IsFalse(Algorithm.LexicographicalCompare(v1.Begin, v1.End, v1.Begin, v1.End, Compare.Less(Of Integer)()))
            Assert.IsTrue(Algorithm.LexicographicalCompare(v1.Begin, v1.End, l2.Begin, l2.End, Compare.Less(Of Integer)()))
            Assert.IsTrue(Algorithm.LexicographicalCompare(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice))
        End Sub
        <Test()> _
        Public Sub max()
            Assert.AreEqual(4, Algorithm.Max(2, 4, Compare.Less(Of Integer)()))
            Assert.AreNotEqual(2, Algorithm.Max(2, 4, Compare.Less(Of Integer)()))
        End Sub
        <Test()> _
       Public Sub min()
            Assert.AreEqual(2, Algorithm.Min(2, 4, Compare.Less(Of Integer)()))
        End Sub
        <Test()> _
        Public Sub max_element()
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, -6, -8, -99, -5})
            Assert.AreEqual(Algorithm.MaxElement(Of Integer, Vector(Of Integer).Iterator)(v1.Begin, v1.End).Value, 25)
            Assert.AreEqual(Algorithm.MaxElement(v1.Begin, v1.End, New mod_less_int).Value, -99)
        End Sub
        <Test()> _
        Public Sub min_element()
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, -6, -8, -99, -5})
            Assert.AreEqual(Algorithm.MinElement(Of Integer, Vector(Of Integer).Iterator)(v1.Begin, v1.End).Value, -99)
            Assert.AreEqual(Algorithm.MinElement(v1.Begin, v1.End, New mod_less_int).Value, 0)
        End Sub
        <Test()> _
        Public Sub next_permutation()
            Dim v1 As New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3})

            Assert.IsTrue(Algorithm.NextPermutation(v1.Begin, v1.End, New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {-3, -2, -1, 0, 1, 3, 2}))

            Assert.IsTrue(Algorithm.NextPermutation(v1.Begin, v1.End, New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {-3, -2, -1, 0, 2, 1, 3}))

            Assert.IsTrue(Algorithm.NextPermutation(v1.Begin, v1.End, New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {-3, -2, -1, 0, 2, 3, 1}))

        End Sub
        <Test()> _
        Public Sub nth_element()
            Dim v1 As New Vector(Of Integer)(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
            Algorithm.RandomShuffle(v1.Begin, v1.End)

            Dim nth_elem As Vector(Of Integer).Iterator = _
                 v1.Begin + 4


            Algorithm.NthElement(v1.Begin, nth_elem, v1.End, Compare.Less(Of Integer)())

            Dim nth_elemVal As Integer = nth_elem.Value
            Assert.AreEqual(nth_elem.Value, 4)

            ' Test that all before 9 are less and behind 9 are greater!
            Assert.AreEqual(Algorithm.FindIf(v1.Begin, nth_elem, Bind.Second(Compare.Greater(Of Integer)(), nth_elemVal)), nth_elem)
            Assert.AreEqual(Algorithm.FindIf(nth_elem, v1.End, Bind.Second(Compare.Less(Of Integer)(), nth_elemVal)), v1.End)

        End Sub
        <Test()> _
        Public Sub partial_sort_copy()
            Dim v1 As New Vector(Of Integer)(4, 10, 70, 30, 10, 69, 96, 7)
            Dim v2 As New Vector(Of Integer)(0, 0, 0, 0)

            Algorithm.PartialSortCopy(v1.Begin, v1.End, v2.Begin, v2.End, Compare.Less(Of Integer)())

            Assert.IsFalse(TestUtil.mismatch(v2, New Integer() {4, 7, 10, 10}))
        End Sub
        <Test()> _
        Public Sub partition()

            Dim num As Integer = 5
            Dim v1 As New Vector(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})

            'test fwd it version
            Algorithm.RandomShuffle(v1.Begin, v1.End)
            Dim res As Vector(Of Integer).Iterator = _
                Algorithm.Partition(v1.Begin, v1.End, Bind.Second(Compare.Greater(Of Integer)(), num))

            Dim f As Vector(Of Integer).Iterator = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.LessEqual(Of Integer)(), num))
            Assert.AreEqual(Algorithm.FindIf(v1.Begin, f, Bind.Second(Compare.LessEqual(Of Integer)(), num)), f)
            Assert.AreEqual(Algorithm.FindIf(f, v1.End, Bind.Second(Compare.Greater(Of Integer)(), num)), v1.End)

            'test bidit it version
            Algorithm.RandomShuffle(v1.Begin, v1.End)
            Algorithm.Partition(New BidirectionalIteratorProxy(Of Integer)(v1.Begin), New BidirectionalIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.Greater(Of Integer)(), num))

            f = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.LessEqual(Of Integer)(), num))
            Assert.AreEqual(Algorithm.FindIf(v1.Begin, f, Bind.Second(Compare.LessEqual(Of Integer)(), num)), f)
            Assert.AreEqual(Algorithm.FindIf(f, v1.End, Bind.Second(Compare.Greater(Of Integer)(), num)), v1.End)


        End Sub
        <Test()> _
        Public Sub partition2()
            Dim v1 As New Vector(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
            Algorithm.Partition(v1.Begin, v1.End, Compose.FGx(Bind.Second(Compare.EqualTo(Of Integer)(), 0), Bind.Second(New mod_int, 2)))

            Assert.IsTrue(TestUtil.equal(v1, 10, 2, 8, 4, 6, 5, 7, 3, 9, 1))
        End Sub

        <Test()> _
        Public Sub prev_permutation()
            Dim v1 As New Vector(Of Integer)(New Integer() {1, 5, 10})
            Assert.IsFalse(Algorithm.PrevPermutation(v1.Begin, v1.End(), Compare.Less(Of Integer)()))
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {10, 5, 1})))

            v1 = New Vector(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3})
            Assert.IsTrue(Algorithm.PrevPermutation(v1.Begin, v1.End(), New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {-3, -2, 1, 3, 2, -1, 0})))

            Assert.IsTrue(Algorithm.PrevPermutation(v1.Begin, v1.End(), New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {-3, -2, 1, 3, 2, 0, -1})))

            Assert.IsTrue(Algorithm.PrevPermutation(v1.Begin, v1.End(), New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {-3, -2, 1, 3, -1, 2, 0})))
        End Sub
        <Test()> _
        Public Sub replace_if()
            Dim v1 As New Vector(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Algorithm.ReplaceIf(v1.Begin(), v1.End(), Bind.Second(Compare.Greater(Of Integer)(), 6), 77)
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {77, 1, 77, 2, 0, 77, 77, 3, 4, 6, 77, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub replace()
            Dim v1 As New Vector(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Algorithm.Replace(v1.Begin(), v1.End(), 7, 77)
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {77, 1, 9, 2, 0, 77, 77, 3, 4, 6, 8, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub replace_copy_if()
            Dim v1 As New Vector(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            Dim v2 As New Vector(Of Integer)
            Algorithm.ReplaceCopyIf(v1.Begin(), v1.End(), NStlUtil.BackInserter(v2), Bind.Second(Compare.Greater(Of Integer)(), 6), 77)
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(New Integer() {77, 1, 77, 2, 0, 77, 77, 3, 4, 6, 77, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub replace_copy()
            Dim v1 As New Vector(Of Integer)(7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7)
            Dim v2 As New Vector(Of Integer)
            Algorithm.ReplaceCopy(v1.Begin(), v1.End(), NStlUtil.BackInserter(v2), 7, 77)
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(New Integer() {77, 1, 9, 2, 0, 77, 77, 3, 4, 6, 8, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub stable_partition()
            Dim v1a As New Vector(Of Integer)(5, 1, 9, 2, 0, 5, 7, 3, 4, 5, 8, 5, 5, 5, 10, 6)

            Algorithm.StablePartition(v1a.Begin, v1a.End, Bind.Second(Compare.Greater(Of Integer)(), 5))

            Assert.IsFalse(TestUtil.mismatch(v1a, New Vector(Of Integer)(New Integer() {9, 7, 8, 10, 6, 5, 1, 2, 0, 5, 3, 4, 5, 5, 5, 5})))

        End Sub
        <Test()> _
        Public Sub stable_sort()
            Dim n0_1 As New TestInteger(0)
            Dim n2_1 As New TestInteger(2)
            Dim n4_1 As New TestInteger(4)
            Dim n6_1 As New TestInteger(6)
            Dim n8_1 As New TestInteger(8)
            Dim n10_1 As New TestInteger(10)

            Dim n0_2 As New TestInteger(0)
            Dim n2_2 As New TestInteger(2)
            Dim n4_2 As New TestInteger(4)
            Dim n6_2 As New TestInteger(6)
            Dim n8_2 As New TestInteger(8)
            Dim n10_2 As New TestInteger(10)


            Dim v1 As New Vector(Of TestInteger)( _
                n0_1, _
                n2_1, _
                n4_1, _
                n6_1, _
                n8_1, _
                n10_1, _
                n0_2, _
                n2_2, _
                n4_2, _
                n6_2, _
                n8_2, _
                n10_2 _
                )

            ' Test sorting
            Dim extractInt As IUnaryFunction(Of TestInteger, Integer) = _
                Functional.PtrFun(Of TestInteger, Integer)(AddressOf TestInteger.GetInt)

            Dim less As IBinaryFunction(Of TestInteger, TestInteger, Boolean) = _
                Compose.FGxHy(Of TestInteger, TestInteger, Integer, Integer, Boolean)(Compare.Less(Of Integer)(), extractInt, extractInt)

            Algorithm.StableSort(v1.Begin, v1.End, less)

            Dim vExpected As New Vector(Of TestInteger)(n0_1, n0_2, n2_1, n2_2, n4_1, n4_2, n6_1, n6_2, n8_1, n8_2, n10_1, n10_2)

            Assert.AreEqual(v1.Count(), vExpected.Count())
            Assert.IsTrue(Algorithm.Equal(v1.Begin, v1.End, vExpected.Begin))

        End Sub

        Private Class TestInteger
            Public Sub New(ByVal i As Integer)
                Me.i = i
            End Sub
            Public ReadOnly Property Int() As Integer
                Get
                    Return i
                End Get
            End Property
            Public Shared Function GetInt(ByVal ii As TestInteger) As Integer
                Return ii.Int
            End Function
            Public i As Integer = 0
            Public Overrides Function ToString() As String
                Return String.Format("{0} - {1}", Me.GetHashCode, i)
            End Function
        End Class

        <Test()> _
        Public Sub unique_copy()
            Dim v1 As New Vector(Of Integer)(New Integer() {5, -5, 5, -5, 4, 4, 4, 7, 10, 10, 10, 10, 10, 10})


            'inplace unique
            Algorithm.UniqueCopy(v1.Begin, v1.Begin() + 8, v1.Begin() + 8, Compare.EqualTo(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {5, -5, 5, -5, 4, 4, 4, 7, 5, -5, 5, -5, 4, 7})))
            Dim v2 As New Vector(Of Integer)(v1.Count)
            Algorithm.UniqueCopy(v1.Begin, v1.End(), v2.Begin(), New abs_mod_equal)
            v2.Erase(Algorithm.RemoveIf(v2.Begin, v2.End, Functional.IsDefault(Of Integer)()), v2.End())
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(New Integer() {5, 4, 7, 5, 4, 7})))
        End Sub
        <Test()> _
        Public Sub unique()
            Dim v1 As New Vector(Of Integer)(5, -5, 5, -5, 4, 4, 4, 7, 10, 10, 10, 10, 10, 10)
            Dim v2 As New Vector(Of Integer)(5, -5, 5, -5, 4, 4, 4, 7, 10, 10, 10, 10, 10, 10)

            'Algorithm.sort(v1.begin, v1.end)
            v1.Erase(Algorithm.Unique(v1.Begin, v1.End, Compare.EqualTo(Of Integer)()), v1.End)
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {5, -5, 5, -5, 4, 7, 10})))

            v2.Erase(Algorithm.Unique(v2.Begin, v2.End, New abs_mod_equal), v2.End)
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(New Integer() {5, 4, 7, 10})))

        End Sub
        <Test()> _
        Public Sub accumulate()
            Dim v1 As New Vector(Of Integer)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
            Dim o As Integer = Algorithm.Accumulate(v1.Begin, v1.End, 0, New plus_int)
            Assert.AreEqual(o, 210)
        End Sub
        <Test()> _
        Public Sub adjacent_difference()
            Dim v1 As New Vector(Of Integer)
            Dim v2 As New Vector(Of Integer)
            Dim l1 As New Vector(Of Integer)(New Integer() {1, 4, 9, 16, 25, 36, 49, 64, 81, 100})

            Algorithm.AdjacentDifference(l1.Begin, l1.End, NStlUtil.BackInserter(v1), New minus_int)
            Assert.IsFalse(TestUtil.mismatch(v1, New Vector(Of Integer)(New Integer() {1, 3, 5, 7, 9, 11, 13, 15, 17, 19})))

            Algorithm.AdjacentDifference(l1.Begin, l1.End, NStlUtil.BackInserter(v2), New multiplies_int)
            Assert.IsFalse(TestUtil.mismatch(v2, New Vector(Of Integer)(1, 4, 36, 144, 400, 900, 1764, 3136, 5184, 8100)))

        End Sub
        <Test()> _
        Public Sub inner_product()
            Dim v1 As New Vector(Of Integer)(1, 2, 3, 4, 5, 6, 7)
            Dim l1 As New Vector(Of Integer)(1, 2, 3, 4, 5, 6, 7)

            Dim res As Integer = Algorithm.InnerProduct(v1.Begin, v1.End, l1.Begin, 0, New plus_int, New multiplies_int)
            Assert.AreEqual(res, 140)
        End Sub
        <Test()> _
        Public Sub partial_sum()
            Dim v1 As New Vector(Of Integer)(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
            Dim l1 As New Vector(Of Integer)
            Algorithm.PartialSum(v1.Begin, v1.End, NStlUtil.BackInserter(l1), New plus_int)
            Assert.IsFalse(TestUtil.mismatch(l1, New Vector(Of Integer)(New Integer() {1, 3, 6, 10, 15, 21, 28, 36, 45, 55})))
        End Sub
        <Test()> _
        Public Sub TwoContainerRemove()
            Dim v As New Vector(Of Integer)
            For i As Integer = 0 To 9
                v.PushBack(i)
            Next
            Algorithm.RandomShuffle(v.Begin, v.End)

            Dim m As New Map(Of Integer, String)(Compare.Less(Of Integer)())
            Algorithm.Transform(v.Begin(), v.End(), NStlUtil.Inserter(m, m.Begin()), New Vec2Map)

            m.Erase(0)
            m.Erase(2)
            m.Erase(4)
            m.Erase(6)
            m.Erase(8)

            'Dim callFind As IBinaryFunction(Of Map(Of Integer, String), Integer, Map(Of Integer, String).Iterator) = _
            '    Functional.PtrFun(Of Map(Of Integer, String), Integer, Map(Of Integer, String).Iterator)(AddressOf FindInMap)

            'Dim callFindBound As IUnaryFunction(Of Integer, Map(Of Integer, String).Iterator) = _
            '    Bind.First(callFind, m)

            'Dim compareFOrEndIt As UnaryFunction = Compose.FGx(Bind.First(Compare.EqualTo(Of bidirectional_iterator(Of pair(Of Integer, String)))(), m.end()), callFind)


            v.Erase(Algorithm.RemoveIf(v.Begin, v.End(), _
                                    Compose.FGx( _
                                         Bind.First(Compare.EqualTo(Of Map(Of Integer, String).Iterator)(), m.End()), _
                                            Bind.First(Functional.PtrFun(Of Map(Of Integer, String), Integer, Map(Of Integer, String).Iterator)(AddressOf FindInMap), m) _
                                                     ) _
                                  ), _
                        v.End())


            Algorithm.Sort(v.Begin, v.End)
            Assert.IsFalse(TestUtil.mismatch(v, New Vector(Of Integer)(1, 3, 5, 7, 9)))
        End Sub
        Private Shared Function FindInMap(Of Key, Value)(ByVal m As Map(Of Key, Value), ByVal k As Key) As Map(Of Key, Value).Iterator
            Return m.Find(k)
        End Function
    End Class
End Namespace


